package org.apache.cordova;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.net.Uri;
import android.os.Build;
import android.os.Handler;
import android.os.Looper;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.jh.ios.forecast.R;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.DecimalFormat;
import java.util.zip.CRC32;
import java.util.zip.CheckedInputStream;
import java.util.zip.ZipInputStream;

import ir.mahdi.mzip.zip.ZipArchive;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;

public class LoadingView extends RelativeLayout {


    private TextView statesText;
    private ProgressBar progressBar;
    private Context context;
    private LayoutInflater inflater;
    private LoadFinish loadFinish;
    private String serverVersion;
    private Button button;
    private int progress = 0;
    private TextView version;
    private ProgressDialog progressDialog;
    public Activity activity;
    public LoadFinish getLoadFinish() {
        return loadFinish;
    }

    public void setProgress(int progress) {
        this.progress = progress;
        progressBar.setProgress(progress);
    }

    public void setLoadFinish(LoadFinish loadFinish) {
        this.loadFinish = loadFinish;
    }

    public LoadingView(Context context) {
        super(context);
        this.context = context;
        this.inflater = LayoutInflater.from(context);
    }

    public LoadingView(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        this.inflater = LayoutInflater.from(context);

    }

    public LoadingView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.context = context;
    }

    private void initSubView() {
        statesText = findViewById(R.id.stateText);
        progressBar = findViewById(R.id.progressBar);
        button = findViewById(R.id.button);
        version = findViewById(R.id.version);
        button.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                getAppVersion();
            }
        });
        getAppVersion();


    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        initSubView();
    }
//检查更新
    private void getAppVersion() {
        button.setVisibility(View.GONE);
        progressBar.setProgress(View.GONE);
        statesText.setVisibility(View.VISIBLE);
        String channelNumber = getAppMetaData(this.context, "UMENG_CHANNEL");//获取app当前的渠道号
        Log.e("efsfdfcv","渠道号："+channelNumber);
        String url = "http://47.244.180.213:8200/api/package/getPackage?stageType=mk&downloadChannel="+channelNumber+"&packageName=android";
        Log.e("efsfdfcv","地址："+url);
//        String url = "http://192.168.103.3/ionic/lottery/933android/info.json";
//        String url = "http://192.168.103.41/zjjh/android/info.json";
//        String url = "http://192.168.10.39/ionic/lottery/android/info.json";

        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();

        Call call = client.newCall(request);

        //4,将请求添加到调度中
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                Handler mainThread = new Handler(Looper.getMainLooper());
                mainThread.post(new Runnable() {
                    @Override
                    public void run() {
                        button.setText("检查更新失败,重试");
                        button.setVisibility(View.VISIBLE);
                        progressBar.setProgress(View.GONE);
                        statesText.setVisibility(View.GONE);
                    }
                });
            }
            @Override
            public void onResponse(Call call, Response response) throws IOException {

                if (response.isSuccessful()) {
                    final String message = response.body().string();
                    Handler mainThread = new Handler(Looper.getMainLooper());
                    mainThread.post(new Runnable() {
                        @Override
                        public void run() {
                            try {
                                JSONObject jsonObject = new JSONObject(message);
                                JSONObject android = jsonObject.getJSONObject("data");
                                Log.i("info",message);
                                String appVersion = android.getString("appVersion");

                                if(getAppVersionName().equals(appVersion)){
                                    SharedPreferences preferences = context.getSharedPreferences("ionic_SDK",
                                            Context.MODE_PRIVATE);
                                    SharedPreferences.Editor editor = preferences.edit();
                                    String versionStr = preferences.getString("appVersion", "");
                                    serverVersion = android.getString("version");
                                    version.setText("版本："+serverVersion);
                                    if ("".equals(versionStr) || versionStr == null || !versionStr.equals(serverVersion)) {
                                        deleteSingleFile(FileManager.getFilePath()+"/www");
                                        editor.putString("appVersion","0.0.0");
                                        downloadPackage(android.getString("url"));
                                    }else {
                                        loadingWebView();
                                        if (loadFinish != null){
                                            loadFinish.finish();
                                        }
                                    }
                                }else {
                                    showUpdaloadDialog(android.getString("appUrl"));
                                }



                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    });
                }else {
                    Handler mainThread = new Handler(Looper.getMainLooper());
                    mainThread.post(new Runnable() {
                        @Override
                        public void run() {
                            button.setText("检查更新失败,重试");
                            button.setVisibility(View.VISIBLE);
                            progressBar.setProgress(View.GONE);
                            statesText.setVisibility(View.GONE);
                        }
                    });
                }
            }
        });
    }

    /**
     * 获取app当前的渠道号或application中指定的meta-data
     *
     * @return 如果没有获取成功(没有对应值，或者异常)，则返回值为空
     */
    public static String getAppMetaData(Context context, String key) {
        if (context == null || TextUtils.isEmpty(key)) {
            return null;
        }
        String channelNumber = null;
        try {
            PackageManager packageManager = context.getPackageManager();
            if (packageManager != null) {
                ApplicationInfo applicationInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA);
                if (applicationInfo != null) {
                    if (applicationInfo.metaData != null) {
                        channelNumber = applicationInfo.metaData.getString(key);
                    }
                }
            }
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return channelNumber;
    }

//    注：上面所说的key指的是清单文件中你在注册友盟统计时的"UMENG_CHANNEL"（即getChannelNumber(Context context, String key)方法的第二个参数key传入"UMENG_CHANNEL"），而不是"UMENG_APPKEY"，也不是任何一个value值
//            <!-- 友盟统计 -->
//    <meta-data
//    android:name="UMENG_APPKEY"
//    android:value="*****************" />
//    <meta-data
//    android:name="UMENG_CHANNEL"
//    android:value="${UMENG_CHANNEL_VALUE}" />
//    /**
//     * 在需要的地方调用上述方法
//     */
//    String channelNumber = getAppMetaData(getBaseContext(), "UMENG_CHANNEL");//获取app当前的渠道号

    private void showUpdaloadDialog(final String downloadUrl){
        // 这里的属性可以一直设置，因为每次设置后返回的是一个builder对象
        AlertDialog.Builder builder = new AlertDialog.Builder(this.context);
        // 设置提示框的标题
        builder.setTitle("版本升级").
                setIcon(R.mipmap.logo). // 设置提示框的图标
                setMessage("发现新版本！请及时更新").// 设置要显示的信息
                setPositiveButton("确定", new DialogInterface.OnClickListener() {// 设置确定按钮
            @Override
            public void onClick(DialogInterface dialog, int which) {
                startUpload(downloadUrl);//下载最新的版本程序
            }
        }).setNegativeButton("取消", new DialogInterface.OnClickListener(){

            @Override
            public void onClick(DialogInterface dialog, int which) {
                System.exit(0);
            }
        });//设置取消按钮,null是什么都不做，并关闭对话框
        AlertDialog alertDialog = builder.create();
        // 显示对话框
        alertDialog.show();
    }

    private void startUpload(String url){

        Log.i("url",url);
        File dir = new File(FileManager.getFilePath());
        Log.i("getFilePath",dir.getPath());
        progressDialog=new ProgressDialog(this.context);
        progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
        progressDialog.setMessage("正在下载新版本");
        progressDialog.setCancelable(false);//不能手动取消下载进度对话框
        progressDialog.show();
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败监听回调
                Handler mainThread = new Handler(Looper.getMainLooper());
                mainThread.post(new Runnable() {
                    @Override
                    public void run() {
                        button.setText("下载资源失败,重试");
                        button.setVisibility(View.VISIBLE);
                        progressBar.setProgress(View.GONE);
                        statesText.setVisibility(View.GONE);
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                // 储存下载文件的目录
                final File file = new File(context.getFilesDir(),"app.apk");
                try {
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        final int progress = (int) (sum * 1.0f / total * 100);
                        final String totalString = formetFileSize(total);
                        final String current = formetFileSize(sum);
                        Log.i("current",current);
                        Handler mainThread = new Handler(Looper.getMainLooper());
                        mainThread.post(new Runnable() {
                            @Override
                            public void run() {
                                progressDialog.setProgress(progress);
                            }
                        });
                    }
                    fos.flush();
                    openAPK(file);
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });

    }

    private void openAPK(File file){
        Log.i("apkPath",file.getPath());
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            Uri contentUri = FileProvider.getUriForFile(this.context, "com.jh.android.zjjh933.fileprovider", file); //和Manifest注册的一致，原理就是，在应用的Manifest注册你的授权，而且保证是唯一的，那么你通过fileprovider方式从file拿uri的时候，你要验证你的授权
            intent.setDataAndType(contentUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");

        }
        this.activity.startActivity(intent);
    }


    public static String getAppVersionName() {
        String versionName = "";
        try {
            PackageManager pm = MainApplication.getContent().getPackageManager();
            PackageInfo pi = pm.getPackageInfo(MainApplication.getContent().getPackageName(), 0);
            versionName = pi.versionName;
            if (versionName == null || versionName.length() <= 0) {
                return "";
            }
        } catch (Exception e) {
            Log.e("VersionInfo", "Exception", e);
        }
        return versionName;
    }

    private void downloadPackage(String url) {
        statesText.setText("资源下载中...");
        progressBar.setVisibility(VISIBLE);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder().url(url).build();
        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                // 下载失败监听回调
                Handler mainThread = new Handler(Looper.getMainLooper());
                mainThread.post(new Runnable() {
                    @Override
                    public void run() {
                        button.setText("下载资源失败,重试");

                        button.setVisibility(View.VISIBLE);
                        progressBar.setProgress(View.GONE);
                        statesText.setVisibility(View.GONE);
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                InputStream is = null;
                byte[] buf = new byte[2048];
                int len = 0;
                FileOutputStream fos = null;
                // 储存下载文件的目录
                File dir = new File(FileManager.getFilePath());
                final File file = new File(dir,"www.zip");
                try {
                    is = response.body().byteStream();
                    long total = response.body().contentLength();
                    fos = new FileOutputStream(file);
                    long sum = 0;
                    while ((len = is.read(buf)) != -1) {
                        fos.write(buf, 0, len);
                        sum += len;
                        final int progress = (int) (sum * 1.0f / total * 100);
                        final String totalString = formetFileSize(total);
                        final String current = formetFileSize(sum);
                        Handler mainThread = new Handler(Looper.getMainLooper());
                        mainThread.post(new Runnable() {
                            @Override
                            public void run() {
                                statesText.setText("资源下载中... " + current + " / " + totalString);
                                progressBar.setProgress(progress);
                            }
                        });

                    }
                    fos.flush();
                    unFile();
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        if (is != null)
                            is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        if (fos != null)
                            fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
    }

    private void unFile(){
        Handler mainThread = new Handler(Looper.getMainLooper());
        mainThread.post(new Runnable() {
            @Override
            public void run() {
                statesText.setText("正在解压");
                String zipPath = FileManager.getFilePath()+"/www.zip";
                String outPath = FileManager.getFilePath()+"";
                ZipArchive.unzip(zipPath,outPath,null);
                SharedPreferences preferences = context.getSharedPreferences("ionic_SDK",
                        Context.MODE_PRIVATE);
                SharedPreferences.Editor editor = preferences.edit();
                editor.putString("appVersion",serverVersion);
                editor.commit();
                deleteSingleFile(zipPath);
                loadingWebView();
                if (loadFinish != null){
                    loadFinish.finish();
                }
            }
        });
    }

    public static void deleteSingleFile(String filePath) {
        File file = new File(filePath);
        if (file.isFile()){
            file.delete();// 删除目录本身
        }else if(file.isDirectory()){
            for (File f : file.listFiles()) {
                if (f.isFile()){
                    f.delete(); // 删除所有文件
                } else if (f.isDirectory()) {
                    deleteSingleFile(f.getPath()); // 递规的方式删除文件夹
                }
            }
            file.delete();// 删除目录本身
        }

    }

    private void loadingWebView(){
        progressBar.setProgress(0);
        progressBar.setVisibility(View.GONE);
        statesText.setVisibility(VISIBLE);
        statesText.setText("加载资源中...");
    }


    private String formetFileSize(long fileS) {
        DecimalFormat df = new DecimalFormat("#.00");
        String fileSizeString = "";
        String wrongSize = "0B";
        if (fileS == 0) {
            return wrongSize;
        }
        if (fileS < 1024) {
            fileSizeString = df.format((double) fileS) + "B";
        } else if (fileS < 1048576) {
            fileSizeString = df.format((double) fileS / 1024) + "KB";
        } else if (fileS < 1073741824) {
            fileSizeString = df.format((double) fileS / 1048576) + "MB";
        } else {
            fileSizeString = df.format((double) fileS / 1073741824) + "GB";
        }
        return fileSizeString;
    }

    public interface LoadFinish{
        void finish();
    }

}